package com.gdut.huayan.security;

import com.gdut.huayan.constant.SecurityConstant;
import com.gdut.huayan.entity.dto.Result;
import com.gdut.huayan.utils.RedisUtils;
import com.gdut.huayan.utils.StringUtils;
import com.gdut.huayan.utils.WebJsonUtils;
import com.gdut.huayan.utils.WebJwtUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    private RedisUtils redisUtils;

    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse resp, FilterChain chain) throws ServletException, IOException {
        authorization(req, resp, chain);
    }

    private void authorization(HttpServletRequest req, HttpServletResponse resp, FilterChain chain) throws ServletException, IOException {
        String userToken = req.getHeader(SecurityConstant.AUTHORIZATION_HEADER);
        if ("".equals(userToken) || userToken == null) {
            System.out.println("没有token");
            chain.doFilter(req, resp);
            return;
        }
        String userId = WebJwtUtils.resolve(userToken, SecurityConstant.TOKEN_SECRET);
        if (userId == null) {
            userId = "";
        }
        String redisToken = redisUtils.getHash(SecurityConstant.USER_PREFIX + userId, SecurityConstant.TOKEN_PREFIX);
        if ("".equals(userId) || !userToken.equals(redisToken)) {
            Result result = new Result();
            result.setCode(4005);
            result.setMessage("您的令牌不存在或有误");
            result.setData(null);
            WebJsonUtils.write(resp, result);
            return;
        }
        String role = redisUtils.getHash(SecurityConstant.USER_PREFIX + userId, SecurityConstant.ROLE_PREFIX);//为什么这里是null
        List<GrantedAuthority> list = new ArrayList<>();
        if (StringUtils.isNotEmpty(role)) {
            for (String s : role.split("&")) {
                list.add(new SimpleGrantedAuthority(s));
            }
        }
        //将一个用户标记为已认证并放入安全上下文
        SecurityContextHolder.getContext().setAuthentication(
                new UsernamePasswordAuthenticationToken(userId, userToken, list)
        );
        chain.doFilter(req, resp);
    }
}